package manage.sys.entity;

import java.io.Serializable;
import java.util.List;
import java.util.Map;

import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToMany;
import javax.persistence.ManyToOne;
import javax.persistence.OneToMany;
import javax.persistence.OrderBy;
import javax.persistence.Table;
import javax.validation.constraints.Min;

import org.hibernate.annotations.DynamicInsert;
import org.hibernate.annotations.DynamicUpdate;
import org.hibernate.annotations.Fetch;
import org.hibernate.annotations.FetchMode;
import org.hibernate.annotations.GenericGenerator;
import org.hibernate.validator.constraints.NotBlank;

import com.fasterxml.jackson.annotation.JsonIgnore;
import com.google.common.collect.Lists;

import modules.sys.entity.User;

/**
 * 菜单权限表
 * 
 * @author zzc
 */
@Entity
@Table(name = "manage_menu")
@DynamicInsert
@DynamicUpdate
public class Menu implements Serializable {

	private static final long serialVersionUID = -3952699855794630263L;
	public static final int LEVEL_FIRST = 0;// 一级菜单
	public static final String TYPE_TENANT = "0";// 租户菜单
	public static final String TYPE_MANAGE = "1";// 后台菜单

	private String id;
	/** 父菜单 */
	private Menu parentMenu;
	/** 菜单名称 */
	private String name;
	/** 菜单类型0、租户菜单 1、后台管理菜单 */
	private String type;
	/** 菜单等级 */
	private Integer level;
	/** 菜单地址 */
	private String url;
	/** 菜单排序 */
	private Integer order;
	/** 图标 */
	private String icon;
	/** 子菜单 */
	private List<Menu> childMenus = Lists.newArrayList();
	/** 拥有用户列表 */
	private List<User> userList = Lists.newArrayList();
	/** 拥有管理员列表 */
	private List<ManageUser> manageUserList = Lists.newArrayList();

	@Id
	@GeneratedValue(generator = "paymentableGenerator")
	@GenericGenerator(name = "paymentableGenerator", strategy = "uuid")
	@Column(name = "id", nullable = false, length = 32)
	public String getId() {
		return id;
	}

	public void setId(String id) {
		this.id = id;
	}

	@ManyToOne(fetch = FetchType.LAZY)
	@JoinColumn(name = "pid")
	@JsonIgnore
	public Menu getParentMenu() {
		return parentMenu;
	}

	public void setParentMenu(Menu parentMenu) {
		this.parentMenu = parentMenu;
	}

	@Column(name = "name", nullable = false, length = 50)
	@NotBlank(message = "名称不能为空")
	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	@Column(name = "type", nullable = false, length = 10)
	@NotBlank(message = "类型不能为空")
	public String getType() {
		return type;
	}

	public void setType(String type) {
		this.type = type;
	}

	@Column(name = "level")
	@Min(0)
	public Integer getLevel() {
		return level;
	}

	public void setLevel(Integer level) {
		this.level = level;
	}

	@Column(name = "url", length = 100)
	public String getUrl() {
		return url;
	}

	public void setUrl(String url) {
		this.url = url;
	}

	@Column(name = "menu_order")
	@Min(0)
	public Integer getOrder() {
		return order;
	}

	public void setOrder(Integer order) {
		this.order = order;
	}

	@Column(name = "icon", length = 50)
	public String getIcon() {
		return icon;
	}

	public void setIcon(String icon) {
		this.icon = icon;
	}

	@OneToMany(cascade = { CascadeType.PERSIST, CascadeType.MERGE,
			CascadeType.REFRESH }, fetch = FetchType.LAZY, mappedBy = "parentMenu")
	@Fetch(FetchMode.SUBSELECT)
	@OrderBy(value = "order asc")
	@JsonIgnore
	public List<Menu> getChildMenus() {
		return childMenus;
	}

	public void setChildMenus(List<Menu> childMenus) {
		this.childMenus = childMenus;
	}

	@ManyToMany(mappedBy = "menuList", fetch = FetchType.LAZY)
	@Fetch(FetchMode.SUBSELECT)
	@JsonIgnore
	public List<User> getUserList() {
		return userList;
	}

	public void setUserList(List<User> userList) {
		this.userList = userList;
	}

	@ManyToMany(mappedBy = "menuList", fetch = FetchType.LAZY)
	@Fetch(FetchMode.SUBSELECT)
	@JsonIgnore
	public List<ManageUser> getManageUserList() {
		return manageUserList;
	}

	public void setManageUserList(List<ManageUser> manageUserList) {
		this.manageUserList = manageUserList;
	}

	public boolean hasSubMenu(Map<Integer, List<Menu>> map) {
		if (map.containsKey(this.getLevel() + 1)) {
			return hasSubMenu(map.get(this.getLevel() + 1));
		}
		return false;
	}

	public boolean hasSubMenu(List<Menu> menus) {
		for (Menu m : menus) {
			if (m.getParentMenu().getId().equals(this.getId())) {
				return true;
			}
		}
		return false;
	}

}